/////////////////////////////////////////////////////////////////
///   This file is an example solution for TwoTicketsPlus in
///   the ISys Core at Brigham Young University.  Students
///   may use the code as part of the 413 course in their
///   milestones following this one, but no permission is given
///   to use this code is any other way.  Since we will likely
///   use this case again in a future year, please DO NOT post
///   the code to a web site, share it with others, or pass
///   it on in any way.

package edu.byu.intex2.tester;

import java.sql.*;
import java.util.List;
import java.util.LinkedList;

/**
 * A singleton object that CRUD's DayOfWeek objects.
 *
 * @author Conan C. Albrecht <conan@warp.byu.edu>
 * @version 2008-03-03
 */
public class DayOfWeekDAO  {
    
  /////////////////////////////////////////////
  ///   Singleton code
  
  private static DayOfWeekDAO instance = null;
  
  /** Creates a new instance of DayOfWeekDAO */
  private DayOfWeekDAO() {
  }//constructor

  /** Retrieves the single instance of this class */
  public static synchronized DayOfWeekDAO getInstance() {
    if (instance == null) {
      instance = new DayOfWeekDAO();
    }
    return instance;
  }//getInstance
  

  ////////////////////////////////////////////
  ///   CREATE methods
  
  /** Creates a new dayofweek in the database */
  public DayOfWeek create(String id) throws DataException {
    DayOfWeek dayofweek = new DayOfWeek(id);
    dayofweek.setObjectAlreadyInDB(false);
    Cache.getInstance().put(dayofweek.getId(), dayofweek);
    return dayofweek;
  }//create
  
  
  
  ////////////////////////////////////////////
  ///   READ methods
  
  /** Reads an existing dayofweek from the database */
  public DayOfWeek read(String id) throws DataException {
    if (Cache.getInstance().containsKey(id)) {
      return (DayOfWeek)Cache.getInstance().get(id);
    }
    Connection conn = ConnectionPool.getInstance().get();
    try {
      return read(id, conn);
    }catch (Exception e) {
      throw new DataException("An error occurred while reading the business object information.", e);
    }finally {
      ConnectionPool.getInstance().release(conn);
    } 
  }
  
  /** Internal method to read an existing dayofweek from the database */
  synchronized DayOfWeek read(String id, Connection conn) throws Exception {
    if (Cache.getInstance().containsKey(id)) {
      return (DayOfWeek)Cache.getInstance().get(id);
    }
    PreparedStatement stmt = conn.prepareStatement("SELECT * FROM day_of_week where id=?");
    try{
      stmt.setString(1, id);
      ResultSet rs = stmt.executeQuery();
      if (rs.next()) {
        return readRecord(rs, conn);
      }//if
      throw new DataException("DayOfWeek with id '" + id + "' not found.");
    }finally{
      stmt.close();
    }
  }//read
  
  
  /** Internal method to create a dayofweek object from a record */
  synchronized DayOfWeek readRecord(ResultSet rs, Connection conn) throws Exception {
    if (Cache.getInstance().containsKey(rs.getString("id"))) {
      return (DayOfWeek)Cache.getInstance().get(rs.getString("id"));
    }
    DayOfWeek dayofweek = new DayOfWeek(rs.getString("id"));
    dayofweek.setObjectAlreadyInDB(true);
    Cache.getInstance().put(dayofweek.getId(), dayofweek);
    dayofweek.setName(rs.getString("description"));
    dayofweek.setDirty(false);
    
    return dayofweek;
  }//readRecord
  

  
  /////////////////////////////////////////////
  ///   UPDATE methods
  
  /** Saves an existing dayofweek in the database */
  public void save(DayOfWeek dayofweek) throws DataException {
    Connection conn = ConnectionPool.getInstance().get();
    try {
      save(dayofweek, conn);
      conn.commit();
    }catch (Exception e) {
      try{
        conn.rollback();
      }catch (SQLException e2) {
        throw new DataException("Could not roll back the database transaction!", e2);
      }
      throw new DataException("An error occurred while saving the business object information.", e);
    }finally {
      ConnectionPool.getInstance().release(conn);
    } 
  }//update
  
  /** Internal method to update a dayofweek in the database */
  void save(DayOfWeek dayofweek, Connection conn) throws Exception {
    Cache.getInstance().put(dayofweek.getId(), dayofweek);
    if (dayofweek.isObjectAlreadyInDB() && dayofweek.isDirty()) {
      update(dayofweek, conn);
    }else if (dayofweek.isDirty()){
      insert(dayofweek, conn);
    }//if
    
    for (SaleLine si: sale.getLines()) {
      SaleLineDAO.getInstance().save(si, conn);
      
    }
  }//save
  
  /** Saves an existing dayofweek to the database */
  private void update(DayOfWeek dayofweek, Connection conn) throws Exception {
    PreparedStatement stmt = conn.prepareStatement("UPDATE day_of_week SET description=? WHERE id=?");
    try {
      stmt.setString(1, dayofweek.getName());
      stmt.setString(2, dayofweek.getId());
      stmt.execute();
      dayofweek.setDirty(false);
    }finally{
      stmt.close();
    }
  }
  
  /** Inserts a new dayofweek into the database */
  private void insert(DayOfWeek dayofweek, Connection conn) throws Exception {
    PreparedStatement stmt = conn.prepareStatement("INSERT INTO day_of_week (id, description) VALUES (?, ?)");
    try {
      stmt.setString(1, dayofweek.getId());
      stmt.setString(2, dayofweek.getName());
      stmt.execute();
      dayofweek.setObjectAlreadyInDB(true);
      dayofweek.setDirty(false);
    }finally{
      stmt.close();
    }
  }  
  
  
  
  
  
  /////////////////////////////////////////////////
  ///   DELETE methods
  
  /** We do not support deleting of business objects in this application */
  public void delete(DayOfWeek dayofweek) throws DataException {
    throw new RuntimeException("Nice try. The delete function is not supported in this application.");
  }
  

  
  ////////////////////////////////////////////////
  ///   SEARCH methods
  
  /** Retrieves all dayofweeks from the database */
  public List<DayOfWeek> getAll() throws DataException {
    Connection conn = ConnectionPool.getInstance().get();
    try {
      PreparedStatement stmt = conn.prepareStatement("SELECT * FROM day_of_week ORDER BY id");
      return search(stmt, conn);
    }catch (Exception e) {
      try{
        conn.rollback();
      }catch (SQLException e2) {
        throw new DataException("Could not roll back the database transaction!", e2);
      }
      throw new DataException("An error occurred while reading the business object information.", e);
    }finally {
      ConnectionPool.getInstance().release(conn);
    } 
  }
  
  /** Internal method to search by certain fields */
  private List<DayOfWeek> search(PreparedStatement stmt, Connection conn) throws Exception {
    List<DayOfWeek> dayofweeks = new LinkedList<DayOfWeek>();
    try {
      ResultSet rs = stmt.executeQuery();
      while (rs.next()) {
        dayofweeks.add(readRecord(rs, conn));
      }
    }finally{
      stmt.close();
    }
    return dayofweeks;
  }
  
  
  
}//class
